<template>
  <div 
    v-if="visible" 
    class="context-menu"
    :style="menuStyle"
    @click.stop
    @contextmenu.prevent
  >
    <div class="context-menu-content">
      <div 
        v-for="(item, index) in menuItems" 
        :key="index"
        class="context-menu-item"
        :class="{ 
          'disabled': item.disabled,
          'separator': item.type === 'separator',
          'has-children': item.children && item.children.length > 0
        }"
        @click="handleMenuClick(item)"
        @mouseenter="handleMouseEnter(item, index)"
        @mouseleave="handleMouseLeave"
      >
        <!-- 分隔线 -->
        <div v-if="item.type === 'separator'" class="menu-separator"></div>
        
        <!-- 普通菜单项 -->
        <template v-else>
          <div class="menu-item-content">
            <i v-if="item.icon" :class="item.icon" class="menu-icon"></i>
            <span class="menu-label">{{ item.label }}</span>
            <span v-if="item.shortcut" class="menu-shortcut">{{ item.shortcut }}</span>
            <i v-if="item.children && item.children.length > 0" class="menu-arrow">▶</i>
          </div>
          
          <!-- 子菜单 -->
          <div 
            v-if="item.children && item.children.length > 0 && hoveredIndex === index"
            class="submenu"
            :style="submenuStyle"
          >
            <div 
              v-for="(child, childIndex) in item.children" 
              :key="childIndex"
              class="context-menu-item"
              :class="{ 'disabled': child.disabled }"
              @click="handleMenuClick(child)"
            >
              <div class="menu-item-content">
                <i v-if="child.icon" :class="child.icon" class="menu-icon"></i>
                <span class="menu-label">{{ child.label }}</span>
                <span v-if="child.shortcut" class="menu-shortcut">{{ child.shortcut }}</span>
              </div>
            </div>
          </div>
        </template>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'ContextMenu',
  data() {
    return {
      visible: false,
      position: { x: 0, y: 0 },
      menuItems: [],
      hoveredIndex: -1,
      currentTarget: null
    }
  },
  
  computed: {
    menuStyle() {
      return {
        left: `${this.position.x}px`,
        top: `${this.position.y}px`,
        transform: this.getTransform()
      }
    },
    
    submenuStyle() {
      return {
        left: '100%',
        top: '0'
      }
    }
  },
  
  mounted() {
    // 监听全局点击事件，点击其他地方隐藏菜单
    document.addEventListener('click', this.handleGlobalClick);
    document.addEventListener('contextmenu', this.handleGlobalClick);
    document.addEventListener('scroll', this.hide);
    window.addEventListener('resize', this.hide);
  },
  
  beforeDestroy() {
    document.removeEventListener('click', this.handleGlobalClick);
    document.removeEventListener('contextmenu', this.handleGlobalClick);
    document.removeEventListener('scroll', this.hide);
    window.removeEventListener('resize', this.hide);
  },
  
  methods: {
    /**
     * 显示右键菜单
     * @param {MouseEvent} event - 鼠标事件
     * @param {Array} items - 菜单项数组
     * @param {Object} target - 触发目标对象
     */
    show(event, items = [], target = null) {
      if (!items || items.length === 0) {
        this.hide();
        return;
      }
      
      this.menuItems = items;
      this.currentTarget = target;
      this.position = this.calculatePosition(event);
      this.visible = true;
      this.hoveredIndex = -1;
      
      this.$emit('show', { event, items, target });
    },
    
    /**
     * 隐藏右键菜单
     */
    hide() {
      this.visible = false;
      this.hoveredIndex = -1;
      this.currentTarget = null;
      this.$emit('hide');
    },
    
    /**
     * 计算菜单位置，防止超出屏幕
     */
    calculatePosition(event) {
      const { clientX: x, clientY: y } = event;
      const { innerWidth: screenWidth, innerHeight: screenHeight } = window;
      
      // 预估菜单尺寸
      const menuWidth = 200;
      const menuHeight = this.menuItems.length * 32 + 10;
      
      let finalX = x;
      let finalY = y;
      
      // 防止右侧超出
      if (x + menuWidth > screenWidth) {
        finalX = screenWidth - menuWidth - 10;
      }
      
      // 防止底部超出
      if (y + menuHeight > screenHeight) {
        finalY = screenHeight - menuHeight - 10;
      }
      
      // 防止左侧超出
      if (finalX < 0) {
        finalX = 10;
      }
      
      // 防止顶部超出
      if (finalY < 0) {
        finalY = 10;
      }
      
      return { x: finalX, y: finalY };
    },
    
    /**
     * 获取transform样式
     */
    getTransform() {
      return 'translateZ(0)';
    },
    
    /**
     * 处理菜单项点击
     */
    handleMenuClick(item) {
      if (item.disabled || item.type === 'separator') {
        return;
      }
      
      // 如果有子菜单，不关闭菜单
      if (item.children && item.children.length > 0) {
        return;
      }
      
      // 执行回调
      if (typeof item.handler === 'function') {
        item.handler(this.currentTarget);
      }
      
      // 触发事件
      this.$emit('menu-click', {
        item,
        target: this.currentTarget
      });
      
      // 关闭菜单
      this.hide();
    },
    
    /**
     * 处理鼠标进入菜单项
     */
    handleMouseEnter(item, index) {
      if (item.children && item.children.length > 0) {
        this.hoveredIndex = index;
      }
    },
    
    /**
     * 处理鼠标离开菜单项
     */
    handleMouseLeave() {
      // 延迟隐藏子菜单，给用户时间移动到子菜单
      setTimeout(() => {
        if (!this.$el.matches(':hover')) {
          this.hoveredIndex = -1;
        }
      }, 100);
    },
    
    /**
     * 处理全局点击事件
     */
    handleGlobalClick(event) {
      if (this.visible && !this.$el.contains(event.target)) {
        this.hide();
      }
    }
  }
}
</script>

<style scoped>
.context-menu {
  position: fixed;
  z-index: 9999;
  background: #ffffff;
  border: 1px solid #e0e0e0;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  padding: 4px 0;
  min-width: 160px;
  max-width: 300px;
  font-size: 14px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
  user-select: none;
}

.context-menu-content {
  position: relative;
}

.context-menu-item {
  position: relative;
  cursor: pointer;
  transition: background-color 0.2s ease;
}

.context-menu-item:not(.separator):not(.disabled):hover {
  background-color: #f5f5f5;
}

.context-menu-item.disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

.context-menu-item.separator {
  margin: 4px 0;
  cursor: default;
}

.menu-separator {
  height: 1px;
  background-color: #e0e0e0;
  margin: 0 8px;
}

.menu-item-content {
  display: flex;
  align-items: center;
  padding: 8px 16px;
  min-height: 16px;
}

.menu-icon {
  width: 16px;
  height: 16px;
  margin-right: 8px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
}

.menu-label {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.menu-shortcut {
  margin-left: 16px;
  font-size: 12px;
  color: #999;
  opacity: 0.8;
}

.menu-arrow {
  margin-left: 8px;
  font-size: 10px;
  color: #999;
  transform: scale(0.8);
}

.submenu {
  position: absolute;
  background: #ffffff;
  border: 1px solid #e0e0e0;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  padding: 4px 0;
  min-width: 160px;
  z-index: 10000;
}

/* 动画效果 */
.context-menu {
  animation: contextMenuFadeIn 0.15s ease-out;
}

@keyframes contextMenuFadeIn {
  from {
    opacity: 0;
    transform: translateY(-4px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .context-menu {
    min-width: 140px;
    font-size: 16px;
  }
  
  .menu-item-content {
    padding: 12px 16px;
  }
}
</style>
